package pers.jg.rrsserver.controller

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.google.gson.GsonBuilder
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.*
import pers.jg.rrsserver.entity.User
import pers.jg.rrsserver.mapper.UserMapper
import pers.jg.rrsserver.service.SafeService
import pers.jg.rrsserver.service.TelCodeService


@RestController
@CrossOrigin
class UserController {

    @Autowired
    private lateinit var userMapper: UserMapper

    @Autowired
    lateinit var telCodeService: TelCodeService

    @Autowired
    lateinit var safeService: SafeService

    open class Response {
        var result = ""
    }

    class TelCodeResponse : Response() {
        var code = ""
    }

    /**
     * 获取手机验证码API
     * @param tel 手机号
     * @return result: telNull(手机号为空) | ok(发送成功)
     * code: 发送成功的验证码
     */
    @GetMapping("/api/getTelCode")
    fun getTelCode(
        @RequestParam(value = "tel", defaultValue = "") tel: String
    ): String {

        val res = TelCodeResponse()
        val gson = GsonBuilder()
            .create()

        if (tel == "") {
            res.result = "telNull"
            return gson.toJson(res)
        }

        res.code = telCodeService.sendTo(tel).code
        res.result = "ok"
        return gson.toJson(res)
    }

    class ResponseWithUser : Response() {
        lateinit var user: User
    }

    /**
     * 获取通过手机登录API
     * @param tel 提交的手机号
     * @param code 提交的验证码
     * @return result: telNull(手机号为空) | codeNull(验证码为空) | telAndCodeNotFound(验证码错误) | newUserRegistered(新用户注册) | userLogin(用户登录)
     * user: 登录或注册成功的用户
     */
    @GetMapping("/api/loginByTel")
    fun loginByTel(
        @RequestParam(value = "tel", defaultValue = "") tel: String,
        @RequestParam(value = "code", defaultValue = "") code: String
    ): String {

        val gson = GsonBuilder()
            .create()

        val res = ResponseWithUser()

        if (tel == "") {
            res.result = "tellNull"
            return gson.toJson(res)
        } else if (code == "") {
            res.result = "codeNull"
            return gson.toJson(res)
        }

        // 校验验证码
        if (!telCodeService.validateCode(tel, code)) {
            res.result = "telAndCodeNotFound"
            return gson.toJson(res)
        }

        // 查找用户
        val wrapper = QueryWrapper<User>()
        wrapper.eq("tel", safeService.des3Encrypt(tel, System.getenv("RRS_USER_TEL_KEY")))
        val user = userMapper.selectOne(wrapper)

        //手机号未注册，直接注册
        if (user == null) {
//            创建用户
            val newUser = User()
            newUser.tel = tel
            newUser.username = "用户${tel.substring(tel.length - 4)}"

//            加密用户
            val newUserEncrypt = User()
            newUserEncrypt.tel = safeService.des3Encrypt(newUser.tel!!, System.getenv("RRS_USER_TEL_KEY"))
            newUserEncrypt.username =
                safeService.des3Encrypt(newUser.username!!, System.getenv("RRS_USER_USERNAME_KEY"))
            userMapper.insert(newUserEncrypt)

            res.result = "newUserRegistered"
            res.user = newUser
            return gson.toJson(res)
        }
        // 手机号未注册
        else {
            res.result = "userLogin"
            user.username = safeService.des3Decrypt(user.username!!, System.getenv("RRS_USER_USERNAME_KEY"))
            res.user = user
            return gson.toJson(res)
        }
    }

    /**
     * 获取通过用户名登录API
     * @param username 提交的用户名（未加密）
     * @param password 提交的密码（未加密）
     * @return result: usernameNotFound(用户名不存在) | passwordError(密码错误) | ok(登录成功)
     * user: 登录或注册成功的用户
     */
    @GetMapping("/api/loginByUsername")
    fun loginByUsername(
        @RequestParam(value = "username", defaultValue = "") username: String,
        @RequestParam(value = "password", defaultValue = "") password: String,
    ): String {

        val res = ResponseWithUser()
        val gson = GsonBuilder()
            .create()
        val s = ""
        // 查找用户名
        val wrapper = QueryWrapper<User>()
        wrapper.eq(
            "username", safeService.des3Encrypt(username, System.getenv("RRS_USER_USERNAME_KEY"))
        )
        val user = userMapper.selectOne(wrapper)

        // 用户名不存在，拒绝登录
        if (user == null) {
            res.result = "usernameNotFound"
            return gson.toJson(res)
            // 用户名存在，校验密码
        } else {
            // 密码错误，拒绝登录
            println(safeService.des3Decrypt(user.password!!, System.getenv("RRS_USER_PASSWORD_KEY")))
            println(password)
            if (safeService.des3Decrypt(user.password!!, System.getenv("RRS_USER_PASSWORD_KEY")) != password) {
                res.result = "passwordError"
                return gson.toJson(res)
            }
            // 密码正确，登录成功
            else {
                res.result = "ok"
                user.username = username
                res.user = user
                return gson.toJson(res)
            }
        }
    }

    /**
     * 手动注册API
     * @param username 提交的用户名（未加密）
     * @param password 提交的密码（未加密）
     * @return result: usernameExist(用户名已存在) | ok(注册成功)
     * user: 登录或注册成功的用户（密码为密文，其他全为明文）
     */
    @PostMapping("/api/reg")
    fun reg(
        @RequestParam(value = "username", defaultValue = "") username: String,
        @RequestParam(value = "password", defaultValue = "") password: String,
    ): String? {

        val res = ResponseWithUser()
        val gson = GsonBuilder()
            .create()

        // 查找用户名
        val wrapper = QueryWrapper<User>()
        wrapper.eq("username", safeService.des3Encrypt(username, System.getenv("RRS_USER_USERNAME_KEY")))
        val user = userMapper.selectOne(wrapper)

        //用户名已存在，拒绝注册
        if (user != null) {
            res.result = "usernameExist"
            return gson.toJson(res)
        } else {
            val newUser = User()
            newUser.username = safeService.des3Encrypt(username, System.getenv("RRS_USER_USERNAME_KEY"))
            newUser.password = safeService.des3Encrypt(password, System.getenv("RRS_USER_PASSWORD_KEY"))
            userMapper.insert(newUser)

            res.result = "ok"
            newUser.username = username
            res.user = newUser
            return gson.toJson(res)
        }

    }

    @GetMapping("/api/getUser")
    fun getUser(
        @RequestParam("id") id: Int
    ): String {
        val user = userMapper.selectById(id)
        if(user == null) {
            return "userNotFound"
        }
        user.username = safeService.des3Decrypt(user.username!!, System.getenv("RRS_USER_USERNAME_KEY"))
        if(user.tel != null) {
            user.tel = safeService.des3Decrypt(user.tel!!, System.getenv("RRS_USER_TEL_KEY"))
        }
        val gson = GsonBuilder()
            .create()
        return gson.toJson(user)
    }

    /**
     * 获取所有用户列表API
     * @return 所有用户列表
     */
    @GetMapping("/api/getUserList")
    fun getUserList(
    ): String {
        val queryWrapper = QueryWrapper<User>()
        val userList = userMapper.selectList(queryWrapper)
        for (user in userList) {
            user.username = safeService.des3Decrypt(user.username!!, System.getenv("RRS_USER_USERNAME_KEY"))
            user.password = ""
            if (user.tel != null) {
                user.tel = safeService.des3Decrypt(user.tel!!, System.getenv("RRS_USER_TEL_KEY"))
            }
        }
        val gson = GsonBuilder()
            .create()
        return gson.toJson(userList)
    }

    /**
     * 更新用户权限API
     * @param id 用户id
     * @param permission 权限名称
     * @param to 是否赋予权限
     * @return result: ok(更新成功)
     */
    @PostMapping("/api/updateUserPermission")
    fun updateUserPermission(
        @RequestParam(value = "id") id: Int,
        @RequestParam(value = "permission") permission: String,
        @RequestParam(value = "to") to: Boolean,
    ): String? {

        val queryWrapper = QueryWrapper<User>()
        queryWrapper.eq("id", id)

        val user = User()
        val field = user.javaClass.getDeclaredField(permission)
        field.setAccessible(true)
        field.set(user, to)

        userMapper.update(user, queryWrapper)

        val res = ResponseWithUser()
        res.result = "ok"
        val gson = GsonBuilder()
            .create()
        return gson.toJson(res)
    }

    /**
     * 更新用户信息API
     * @param id 用户id
     * @param prop 要更新的字段名称
     * @param to 要更新的值
     * @return result: ok(更新成功) | exist(用户名或手机号已存在)
     */
    @PostMapping("/api/updateUserInfo")
    fun updateUserInfo(
        @RequestParam(value = "id") id: Int,
        @RequestParam(value = "prop") prop: String,
        @RequestParam(value = "to") to: String,
    ): String? {

        val queryWrapper = QueryWrapper<User>()
        queryWrapper.eq("id", id)

        val res = ResponseWithUser()
        val gson = GsonBuilder()
            .create()

        val key = when (prop) {
            "username" -> System.getenv("RRS_USER_USERNAME_KEY")
            "tel" -> System.getenv("RRS_USER_TEL_KEY")
            "password" -> System.getenv("RRS_USER_PASSWORD_KEY")
            else -> ""
        }

//        检查用户名或手机号是否重复
        if (prop == "username" || prop == "tel") {
            val wrapper = QueryWrapper<User>()
            wrapper.eq(prop, safeService.des3Encrypt(to, key))
            val user = userMapper.selectOne(wrapper)
            if(user != null) {
                res.result = "exist"
                return gson.toJson(res)
            }
        }


        val user = User()
        val field = user.javaClass.getDeclaredField(prop)
        field.setAccessible(true)
        field.set(user, safeService.des3Encrypt(to, key))
        userMapper.update(user, queryWrapper)

        res.result = "ok"
        return gson.toJson(res)
    }
}